﻿using Collector.Certified;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Collector.Device;

namespace Collector.Certified
{
    public partial class CertifiedForm : Form
    {
        private string TAG = "CertifiedForm:";
        private CertifiedSettingForm mSettingFrom;
        private CertifiedMain mCertifiedHandler = new CertifiedMain();
        private PulseApplicantion mApplication = new PulseApplicantion();
        private uint testTmp = 0;

        // 记录200个点用于计算平均压力值
        Queue<double> airPressure_data = new Queue<double>();
        Queue<double> wave_data = new Queue<double>();

        const int QUEUE_AIRPRESSURE_LENGTH = 10;
        const int THREE_BODY_PART_SNR_MAXIMUM = 3;
        double[] baseline_value = new double[THREE_BODY_PART_SNR_MAXIMUM];


        public CertifiedForm()
        {
            Log.Debug("CertifiedForm Entry");
            InitializeComponent();
            this.Width = Screen.PrimaryScreen.Bounds.Width - 60;
            this.Height = Screen.PrimaryScreen.Bounds.Height - 60;
            this.splitContainer1.SplitterDistance = Screen.PrimaryScreen.Bounds.Width - 400;
            this.splitContainer3.SplitterDistance = Screen.PrimaryScreen.Bounds.Width - 640;

            this.toolStripButtonStopScope.Enabled = false;
            this.pictureBox1.Visible = false;
            this.scopeDY.Visible = true;
            this.Shown += new System.EventHandler(this.CertifiedForm_Shown);

            // 注册配置选项改变的通知事件
            AppEvent.RegistEvent(EventId.UpdateInfo, OnUpdateUI);
            //AppEvent.RegistEvent(EventId.UpdateThresholdValue, UpdateThresholdValues);
            AppEvent.RegistEvent(EventId.TestStop, OnTestStop);
            mSettingFrom = new CertifiedSettingForm();
            LogKeys.Init();

            Log.Debug("CertifiedForm Leaved");
        }

        private void CertifiedForm_Shown(object sender, EventArgs e)
        {
            Log.Debug("CertifiedForm_Shown Entry");
            this.Text = Application.ProductName + " - " + Application.ProductVersion;
            //this.label_TestMode.Text = FileConfig.testMode_Info[FileConfig.CommonParam.iSelectedTestmode].mode;

            Log.Debug("CertifiedForm_Shown Leaved");
        }

        private void OnUpdateUI(object sender, AppEventArgs e)
        {
            if (e.State == EventState.UI)
            {
                //var info = e.Reserved;
                if (Convert.ToInt32(e.Reserved) == 0)
                    mCertifiedHandler.Mode = CertifiedMain.RunMode.eMODE_RUN_FACTORY;
                else if(Convert.ToInt32(e.Reserved) == 1)
                {
                    mCertifiedHandler.Mode = CertifiedMain.RunMode.eMODE_RUN_USER;
                } else if(Convert.ToInt32(e.Reserved) == 2)
                {
                    mCertifiedHandler.Mode = CertifiedMain.RunMode.eMODE_RUN_CERTIFIED;
                }
                    
                //更新测试模式状态
                string TestModeInfo = e.Data as string;
                this.label_TestMode.Text = TestModeInfo;

                if (FileConfig.PulseThreeBodyTest())
                {
                    this.textBox_curveValue1.Visible = true;
                    this.textBox_curveValue2.Visible = true;
                    this.label_realtimePulsePressure1.Visible = true;
                    this.label_realtimePulsePressure2.Visible = true;
                    this.textBox_baseline1.Visible = true;
                    this.label1_baseline1.Visible = true;
                    this.textBox_baseline2.Visible = true;
                    this.label1_baseline2.Visible = true;
                    this.textBox_pressed1.Visible = true;
                    this.label2_pulse_diff1.Visible = true;
                    this.textBox_pressed2.Visible = true;
                    this.label2_pulse_diff2.Visible = true;
                }
                else
                {
                    this.textBox_curveValue1.Visible = false;
                    this.textBox_curveValue2.Visible = false;
                    this.label_realtimePulsePressure1.Visible = false;
                    this.label_realtimePulsePressure2.Visible = false;
                    this.textBox_baseline1.Visible = false;
                    this.label1_baseline1.Visible = false;
                    this.textBox_baseline2.Visible = false;
                    this.label1_baseline2.Visible = false;
                    this.textBox_pressed1.Visible = false;
                    this.label2_pulse_diff1.Visible = false;
                    this.textBox_pressed2.Visible = false;
                    this.label2_pulse_diff2.Visible = false;
                }
            }
        }

        private void OnTestStop(object sender, AppEventArgs e)
        {
            if (e.State != EventState.TestStop)
            {
                return;
            }

            this.Invoke(new MethodInvoker(delegate
            {
                // 模拟点击Stop Button按钮
                this.toolStripButtonStopScope.PerformClick();
            }));
        }

        private int DisplayMessageToUI(PulseCommonHelper.Display obj, PulseCommonHelper.Display.DisplayType type)
        {         
            switch(type)
            {
                case PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG:
                {
                    this.ShowMsg(obj.Message, obj.LogLevel);
                }
                break;
                case PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_ITEM:
                {

                }
                break;
                case PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_USER:
                {
                        CertifiedBackendProcessing((CertifiedMain.CertifiedIntention)obj.UserData);
                }
                break;
                default:
                    break;
            }

            return 0;
        }

        private bool CertifiedBackendProcessing(CertifiedMain.CertifiedIntention intent)
        {
            if(intent == null)
            {
                return false;
            }

            switch(intent.Type)
            {
                case CertifiedMain.CertifiedIntention.IntentionType.eINTENT_TYPE_UPDATE_SERIALPORT_LABLE:
                {
                        // 实时刷新测试时间
                        this.msgComPort.Invoke(new EventHandler(delegate
                        {
                            this.msgComPort.Text = intent.Message;
                        }));
                }
                break;
                case CertifiedMain.CertifiedIntention.IntentionType.eINTENT_TYPE_REFRESH_TEST_TIME:
                {

                    BeginInvoke(new Action(() =>
                    {
                        this.labTotalTime.Text = intent.Message;
                    }));
                }
                break;
                case CertifiedMain.CertifiedIntention.IntentionType.eINTENT_TYPE_UPDATE_SENSOR_DATA:
                {
                    DeliveredPulsePressureDataCallback(intent);
                }
                break;
                case CertifiedMain.CertifiedIntention.IntentionType.eINTENT_TYPE_UPDATE_GRAPH_CURVE:
                {
                        getGraphCurveValue(intent);
                }
                break;
                case CertifiedMain.CertifiedIntention.IntentionType.eINTENT_TYPE_UPDATE_BASELINE:
                {
                    double[] baselines = (double[])intent.Data;
                    for (int i = 0; i < THREE_BODY_PART_SNR_MAXIMUM; i++)
                    {
                        baseline_value[i] = baselines[i];
                        this.ShowMsg("Get baseline_value :" + baseline_value[i], LogMsgType.INFO);
                        if (baseline_value[i] > (FileConfig.GetThresholdValue("BaseLine_UPZH") / 32.0) ||
                            baseline_value[i] < (FileConfig.GetThresholdValue("BaseLine_LowZH") / 32.0))
                        {
                                Log.Error(TAG + string.Format("初始静压值不正确:{0}", baseline_value[i]));
                        }

                        if (!FileConfig.PulseThreeBodyTest())
                        {
                            break;
                        }
                    }

                    this.textBox_baseline.Invoke(new EventHandler(delegate
                    {
                        this.textBox_baseline.Text = baseline_value[0].ToString();
                        this.textBox_baseline.BackColor = Color.Green;
                        if (FileConfig.PulseThreeBodyTest())
                        {
                            this.textBox_baseline1.Text = baseline_value[1].ToString();
                            this.textBox_baseline1.BackColor = Color.Green;
                            this.textBox_baseline2.Text = baseline_value[2].ToString();
                            this.textBox_baseline2.BackColor = Color.Green;
                        }
                    }));
                }
                break;
            }

            return true;
        }

        private bool DeliveredPulsePressureDataCallback(CertifiedMain.CertifiedIntention intent)
        {
            PulseProtocolPackage.PressureType type = intent.PressureType;
            switch (type)
            {
                case PulseProtocolPackage.PressureType.ePRESSURE_TYPE_PULSE:
                {
                    BeginInvoke(new Action(() =>
                    {
                        if (FileConfig.PulseThreeBodyTest())
                        {

                            foreach (var item in PulseApplicantion.TBPIndexMap)
                            {
                                double value = intent.AverageData[item.Key];

                                if (item.Value == BodyPart.eBODY_PART_CUN)
                                {
                                    scopeDY.Channels[0].Data.AddYPoint(value - baseline_value[0]);
                                }
                                else if (item.Value == BodyPart.eBODY_PART_GUAN)
                                {
                                    scopeDY.Channels[1].Data.AddYPoint(value - baseline_value[1]);
                                }
                                else if (item.Value == BodyPart.eBODY_PART_CHI)
                                {
                                    scopeDY.Channels[2].Data.AddYPoint(value - baseline_value[2]);
                                }
                            }                        
                        }
                        else
                        {
                            // Update scope plotlab value
                            //if (pluseDataMap.ContainsKey(BodyPart.eBODY_PART_CUN))
                            {
                                //double value = Math.Round(pluseDataMap[BodyPart.eBODY_PART_CUN].Last(), 2);
                                double value = intent.AverageData[0];
                                scopeDY.Channels[0].Data.AddYPoint(value - baseline_value[0]);
                            }
                        }
                    }));                        
                }
                break;
                case PulseProtocolPackage.PressureType.ePRESSURE_TYPE_AIR:
                {
                    double data = (double)intent.Data;
                    if (airPressure_data.Count >= QUEUE_AIRPRESSURE_LENGTH)
                        airPressure_data.Dequeue();//在队列的头部读取和删除一个元素，注意，这里读取元素的同时也删除了这个元素
                    airPressure_data.Enqueue(data);//在队列的末端添加元素

                }
                break;
            }
        
            return true;
        }

        private void getGraphCurveValue(CertifiedMain.CertifiedIntention intent)
        {
            double airpresure_value = 0;
            double curveline_value = 0;
            double curDiffValue = 0;

            BeginInvoke(new Action(() =>
            {
                testTmp++;
                if (FileConfig.PulseThreeBodyTest())
                {
                    foreach (var item in PulseApplicantion.TBPIndexMap)
                    {
                        if (item.Value == BodyPart.eBODY_PART_CUN)
                        {
                            //curveline_value = Math.Round(item.Value.Average(), 2);
                            curveline_value = intent.AverageData[item.Key];
                            curDiffValue = Math.Round((curveline_value - baseline_value[0]), 2);
                            //实时显示当前脉压值，1秒上报100次
                            this.textBox_curveValue.Text = curveline_value.ToString();
                            //实时显示脉压差值 单位: mbar
                            this.textBox_pressed.Text = curDiffValue.ToString();

                            //实时显示脉压差值 单位: mmHg
                            //curDiffValue = Math.Round(curDiffValue * 100 / 133.33, 2);
                            //if (testTmp % 10 == 0)
                            //    this.textBox_pressed.Text = curDiffValue.ToString(); // mmHg
                        }
                        else if (item.Value == BodyPart.eBODY_PART_GUAN)
                        {
                            //curveline_value = Math.Round(item.Value.Average(), 2);
                            curveline_value = intent.AverageData[item.Key];
                            curDiffValue = Math.Round((curveline_value - baseline_value[1]), 2);
                            //实时显示当前脉压值，1秒上报100次
                            this.textBox_curveValue1.Text = curveline_value.ToString();
                            //实时显示脉压差值 单位: mbar
                            this.textBox_pressed1.Text = curDiffValue.ToString();

                            //实时显示脉压差值 单位: mmHg
                            //curDiffValue = Math.Round(curDiffValue * 100 / 133.33, 2);
                            //if (testTmp % 10 == 0)
                            //    this.textBox_pressed1.Text = curDiffValue.ToString(); // mmHg
                        }
                        else if (item.Value == BodyPart.eBODY_PART_CHI)
                        {
                            //curveline_value = Math.Round(item.Value.Average(), 2);
                            curveline_value = intent.AverageData[item.Key];
                            curDiffValue = Math.Round((curveline_value - baseline_value[2]), 2);
                            //实时显示当前脉压值，1秒上报100次
                            this.textBox_curveValue2.Text = curveline_value.ToString();
                            //实时显示脉压差值 单位: mbar
                            this.textBox_pressed2.Text = curDiffValue.ToString();

                            //实时显示脉压差值 单位: mmHg
                            //curDiffValue = Math.Round(curDiffValue * 100 / 133.33, 2);
                            //if (testTmp % 10 == 0)
                            //    this.textBox_pressed2.Text = curDiffValue.ToString(); // mmHg
                        }
                    }
                }
                else
                {
                    //if (check && pulseDataMap.ContainsKey(BodyPart.eBODY_PART_CUN))
                    if(true)
                    {

                        curveline_value = (double)intent.AverageData[0];
                        //Log.Debug(TAG + "curveline_value: {0}", curveline_value);
                        //curveline_value = Math.Round(pulseDataMap[BodyPart.eBODY_PART_CUN].Average(), 2);
                        curDiffValue = Math.Round((curveline_value - baseline_value[0]), 2);
                        //实时显示当前脉压值，1秒上报100次
                        this.textBox_curveValue.Text = curveline_value.ToString();
                        //实时显示脉压差值 单位: mbar
                        this.textBox_pressed.Text = curDiffValue.ToString();

                        //实时显示脉压差值 单位: mmHg
                        //curDiffValue = Math.Round(curDiffValue * 100 / 133.33, 2);
                        //if (testTmp % 10 == 0)
                        //    this.textBox_pressed.Text = curDiffValue.ToString(); // mmHg
                    }
                }
                //Log.Debug(TAG + "curveline_value: {0}", curveline_value);
                if (airPressure_data.Count == QUEUE_AIRPRESSURE_LENGTH)
                {
                    double[] pressure = airPressure_data.ToArray();
                    double average = pressure.Average();
                    airpresure_value = Math.Round(average, 2);

                    this.textBox_airPressure.Text = airpresure_value.ToString();//实时显示当前气压值，1秒上报10次

                    //testTmp++;
                    // airpresure_value = Math.Round(airpresure_value / 133.33, 2);
                    //if (testTmp % 10 == 0)
                    //    this.textBox_airPressure.Text = airpresure_value.ToString(); // Pa
                }
            }));
        }

        private void btn_StopReset_Click(object sender, EventArgs e)
        {

        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.ShowMsg("MainForm_FormClosing Click", LogMsgType.INFO);
            if (MessageBox.Show("Exit?", Application.ProductName, MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
            {
                try
                {
                    toolStripButtonStopScope_Click(null, null);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(string.Format("Close MainForm...Delete packet And Kill Process Fail...{0}", ex.Message));
                }
                Dispose();
            }
            else
            {
                e.Cancel = true;
            }
        }

        private void btn_ManualTest_Click(object sender, EventArgs e)
        {

        }

        private void btn_ManualPress_Click(object sender, EventArgs e)
        {
            
        }

        private void btn_RefeshBaseLine_Click(object sender, EventArgs e)
        {

        }

        private void toolStripButtonExit_Click(object sender, EventArgs e)
        {
            this.ShowMsg("Exit_Click", LogMsgType.INFO);
            this.Close();
        }

        private void tsBtn_version_Click(object sender, EventArgs e)
        {
            MessageBox.Show(Application.ProductName + "-" + Application.ProductVersion, "版本信息", MessageBoxButtons.OK);
        }

        private void toolStripButtonOpenLog_Click(object sender, EventArgs e)
        {
            //Process.Start("explorer.exe", Application.StartupPath + "\\logs");
        }

        private void toolStripButtonAnalyse_Click(object sender, EventArgs e)
        {

        }
        private void toolStripButtonReplay_Click_1(object sender, EventArgs e)
        {
           
        }

        private void toolStripButtonSave_Click(object sender, EventArgs e)
        {
            //MatlabSaveToBitmap();
            MessageBox.Show("波形保存成功");
            return;
        }

        private void toolStripButtonStopScope_Click(object sender, EventArgs e)
        {
            this.ShowMsg("StopScope_Click", LogMsgType.INFO);
            this.Invoke((EventHandler)delegate
            {
                this.toolStripButtonRunScope.Enabled = true;
                this.toolStripButtonStopScope.Enabled = false;
                this.btn_RefeshBaseLine.Enabled = false;
                this.btn_ManualPress.Enabled = false;
                this.btn_ManualTest.Enabled = false;
                //this.btn_RunInTest.Enabled = true;
            });

            mCertifiedHandler.stopCertified();
            if (mCertifiedHandler.notifyCertifiedForm != null) {
                mCertifiedHandler.notifyCertifiedForm -= new CertifiedMain.FormNotifyDelegate<PulseCommonHelper.Display>(DisplayMessageToUI);
            }        
        }

        /// 开始测试按钮，点击后开始脉象功能测试
        private void toolStripButtonRunScope_Click(object sender, EventArgs e)
        {
            Log.Debug("toolStripButtonRunScope_Click() Entry");
            if (mCertifiedHandler.Mode != CertifiedMain.RunMode.eMODE_RUN_CERTIFIED)
            {
                Log.Error("toolStripButtonRunScope_Click() current is not certified mode.");
                return;
            }

            Thread nth = new Thread(() =>
            {
                this.Invoke((EventHandler)delegate
                {
                    this.toolStripButtonRunScope.Enabled = false;
                    this.toolStripButtonStopScope.Enabled = true;
                    this.btn_RefeshBaseLine.Enabled = true;
                    //this.btn_ManualPress.Enabled = true;
                    this.btn_ManualTest.Enabled = true;
                    this.btn_StopReset.Enabled = true;
                    //this.btn_RunInTest.Enabled = false;
                    this.scopeDY.Visible = true;
                    this.pictureBox1.Visible = false;
                    //清除listView数据
                    AppEvent.CallEvent(this, new AppEventArgs(EventId.TestStart, 0, EventState.Invalid, null, null));
                    // 清空右侧显示测试结果的文本框
                    this.rtbMsg.Clear();

                    this.scopeDY.Channels[0].Data.Clear();
                    this.scopeDY.Channels[1].Data.Clear();
                    this.scopeDY.Channels[2].Data.Clear();
                    if (this.scopeDY.SizeLimit != 300)
                    {
                        this.scopeDY.SizeLimit = 300;
                        this.scopeDY.RefreshInterval = 100;
                        this.scopeDY.RefreshView();
                    }
                    this.textBox_curveValue.Text = "";
                    this.textBox_baseline.Text = "";
                    this.textBox_pressed.Text = "";
                    this.textBox_airPressure.Text = "";

                });

                this.ShowInfo("Running", Color.Yellow);
                //变量重新初始化
                for (int i = 0; i < THREE_BODY_PART_SNR_MAXIMUM; i++)
                    baseline_value[i] = 0;

                this.wave_data.Clear();
                this.airPressure_data.Clear();



                mCertifiedHandler.notifyCertifiedForm += new CertifiedMain.FormNotifyDelegate<PulseCommonHelper.Display>(DisplayMessageToUI);
                mCertifiedHandler.startCertified();
            });

            nth.Start();                    

            Log.Debug("toolStripButtonRunScope_Click() Leaved");
        }

        private void toolStripButtonConfig_Click(object sender, EventArgs e)
        {
            mSettingFrom.ShowDialog();
        }

        private void ShowInfo(string info, Color clr)
        {
            this.lbEndMsg.Invoke(new EventHandler(delegate
            {
                this.lbEndMsg.ForeColor = clr;
                this.lbEndMsg.Text = info;
            }));
        }

        private void ShowMsg(string msg, LogMsgType msgType)
        {
            Color _color = (msgType == LogMsgType.ERROR ? Color.Red : msgType == LogMsgType.DEBUG ? Color.Blue : Color.Black);
            if (msgType != LogMsgType.MSG)
                Log.Debug(msg);
            if (rtbMsg.InvokeRequired)
            {
                Action<string> act = (obj) =>
                {
                    rtbMsg.SelectionColor = _color;
                    rtbMsg.AppendText(obj + "\r\n");
                    rtbMsg.ScrollToCaret();
                };
                rtbMsg.Invoke(act, msg);
            }
            else
            {
                rtbMsg.SelectionColor = _color;
                rtbMsg.AppendText(msg + "\r\n");
                rtbMsg.ScrollToCaret();
            }
        }
    }
}
